#pragma once
#include <iostream>
#include "test.h"
using namespace std;

class PyObject
{
public:
    int py_int;
    Test *t_ptr = nullptr;
    char py_char;
    double py_double;
    bool responsible = false;

public:
    PyObject(){};
    PyObject &operator=(int num)
    {

        py_int = num;
        cout << "PyObject got a value" << endl;
        if (responsible)
        {
            delete t_ptr; // 负责的值被改变需要得到析构
            responsible = false;
        }
        return *this;
    }
    PyObject &operator=(char c)
    {
        py_char = c;
        cout << "PyObject got a value" << endl;
        if (responsible)
        {
            delete t_ptr; // 负责的值被改变需要得到析构
            responsible = false;
        }
        return *this;
    }
    PyObject &operator=(double num)
    {

        py_double = num;
        cout << "PyObject got a value" << endl;
        if (responsible)
        {
            delete t_ptr; // 负责的值被改变需要得到析构
            responsible = false;
        }
        return *this;
    }
    PyObject &operator=(Test &t)
    {

        t_ptr = &t; // 仅仅保存引用
        cout << "PyObject got a value" << endl;
        cout << "Borrowing" << endl;
        if (responsible)
        {
            delete t_ptr; // 负责的值被改变需要得到析构
            responsible = false;
        }
        return *this;
    }
    PyObject &operator=(Test &&t)
    {
        if (this->t_ptr != nullptr)
        {
            t_ptr = nullptr; // 改变所有权
        }

        cout << "PyObject got a value" << endl;
        t_ptr = new Test(std::move(t)); // 移动构造函数
        if (responsible)
        {
            delete t_ptr; // 负责的值被改变需要得到析构
        }
        cout << "Owning" << endl;
        responsible = true; // 对其负责
        return *this;
    }
    PyObject &operator=(PyObject &p)
    {
        if (t_ptr != nullptr)
        {
            delete t_ptr;
        }
        if (p.t_ptr != nullptr)
        {
            t_ptr = p.t_ptr;
            p.t_ptr = nullptr; // 改变所有权
            cout << "PyObject got a value" << endl;
            if (responsible)
            {
                delete t_ptr; // 负责的值被改变需要得到析构
                responsible = false;
            }
        }
        return *this;
    }
    PyObject &operator=(PyObject *p)
    {
        t_ptr = p->t_ptr; // 仅仅保存引用
        cout << "PyObject got a value" << endl;
        if (responsible)
        {
            delete t_ptr; // 负责的值被改变需要得到析构
            responsible = false;
        }
        cout << "Borrowing" << endl;
        return *this;
    }

    operator Test() const
    {
        Test temp(*t_ptr); // 复制，所有权不变
        return temp;
    }
    operator Test &()
    {
        if (t_ptr != nullptr)
        {
            return *t_ptr; // 返回引用
        }
        else
        {
            throw std::runtime_error("Cannot return reference to Test object when t_ptr is null");
        }
    }

    operator int()
    {
        return py_int;
    }
    operator char()
    {
        return py_char;
    }
    operator double()
    {
        return py_double;
    }
};